﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using Ionic.Zip;
using log4net;

namespace Cnm.Core.Ultities
{
    public static class FileHelper
    {
        private static readonly ILog Logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public static string RenameUploadFile(HttpPostedFileBase file, string folder, int counter = 0)
        {
            try
            {
                var finalFileName = Path.GetFileName(file.FileName);
                
                if(counter > 0)
                {
                    finalFileName = Path.GetFileNameWithoutExtension(file.FileName) + " (" + ((counter).ToString(CultureInfo.InvariantCulture)) + ")" + Path.GetExtension(file.FileName);   
                }
                
                if (File.Exists(HttpContext.Current.Request.MapPath(folder + finalFileName)))
                {
                    //file exists 
                    return RenameUploadFile(file, folder, ++counter);
                }
                //file doesn't exist, upload item but validate first
                return UploadFile(file, folder, finalFileName);
            }
            catch(Exception ex)
            {
                Logger.Error(MethodBase.GetCurrentMethod().Name, ex);
                return null;
            }
        }

        public static string UploadFile(HttpPostedFileBase file,string folder, string fileName)
        {
            var pathNorm = Path.Combine(HttpContext.Current.Request.MapPath(folder), fileName);
            string extension = Path.GetExtension(file.FileName);

            //make sure the file is valid
            if (!ValidateExtension(extension))
            {
                return string.Empty;
            }

            try
            {
                file.SaveAs(pathNorm);

                return fileName;
            }
            catch(Exception ex)
            {
                Logger.Error(MethodBase.GetCurrentMethod().Name, ex);
                return string.Empty;
            }
        }

        public static bool ValidateExtension(string extension)
        {
            try
            {
                extension = extension.ToLower();
                var extensions = new[]
                {
                    ".jpg", ".jpeg", ".png", ".gif", ".pdf", ".rar", ".zip", ".pdf", ".doc", ".docx", ".rtf", ".mp3",
                    ".wma"
                };

                return extensions.Any(t => extension == t.Trim());
            }
            catch (Exception ex)
            {
                Logger.Error(MethodBase.GetCurrentMethod().Name, ex);
                return false;
            }
        }

        public static bool DeleteByFileName(string name, string folder)
        {
            try
            {
                if (File.Exists(HttpContext.Current.Request.MapPath(folder + name)))
                {
                    File.Delete(HttpContext.Current.Request.MapPath(folder + name));
                }
                return true;
            }
            catch(Exception ex)
            {
                Logger.Error(MethodBase.GetCurrentMethod().Name, ex);
                return false;
            }
        }

        public static bool DeleteByFileName(string fullPath)
        {
            if (string.IsNullOrWhiteSpace(fullPath))
                return false;

            try
            {
                if (File.Exists(HttpContext.Current.Request.MapPath(fullPath)))
                {
                    File.Delete(HttpContext.Current.Request.MapPath(fullPath));
                }
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(MethodBase.GetCurrentMethod().Name, ex);
                return false;
            }
        }


        public static List<string> GetAllFileNameFromDir(string pathDir)
        {
            try
            {
                var lstFile = new List<string>();
                var path = HttpContext.Current.Server.MapPath(pathDir);
                var dr = new DirectoryInfo(path);
                dr.Create();
                foreach (FileInfo f in dr.GetFiles())
                {
                    var name = f.Name.Substring(0, f.Name.Length - f.Extension.Length);
                    lstFile.Add(name);
                }
                return lstFile;
            }
            catch
            {
                return null;
            }
        }

        public static byte[] GetFile(string name, string folder)
        {
            var filePath = Path.Combine(HttpContext.Current.Request.MapPath(folder), name);
            if (!File.Exists(filePath))
                return null;
            var fs = File.OpenRead(filePath);
            var data = new byte[fs.Length];
            int br = fs.Read(data, 0, data.Length);
            if (br != fs.Length)
                throw new IOException(folder + name);
            return data;
        }

        public static byte[] GetFile(string fileFullPath)
        {
            var filePath = fileFullPath;
            if (!File.Exists(filePath))
                return null;
            var fs = File.OpenRead(filePath);
            var data = new byte[fs.Length];
            int br = fs.Read(data, 0, data.Length);
            if (br != fs.Length)
                throw new IOException(fileFullPath);
            return data;
        }

        public static byte[] GetFilesByZip(string folder, string[] fileNames)
        {
            var outputStream = new MemoryStream();

            using (var zip = new ZipFile())
            {
                foreach (var fileName in fileNames)
                {
                    if (File.Exists(HttpContext.Current.Request.MapPath(folder + fileName)))
                        zip.AddEntry(CommonHelpers.RemoveVietnameseSign(fileName), GetFile(fileName, folder));
                }
                zip.Save(outputStream);
            }

            outputStream.Position = 0;

            return outputStream.ToArray();
        }
    }
}